package com.ltmonitor.thread;


import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.hibernate.type.TrueFalseType;

import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
import com.ltmonitor.service.IQueryService;
import com.ltmonitor.service.ITransferService;
import com.ltmonitor.util.DateUtil;
import com.ltmonitor.web.util.SpringApplicationContextHolder;

import sun.applet.resources.MsgAppletViewer;

/**
 * 校验809链接状态线程
 * @author Administrator
 *
 */
public class CheckJt809StatusThread extends BasicServiceThread{

	public CheckJt809StatusThread(String name, int sleepNum) {
		super(name, sleepNum);
		// TODO Auto-generated constructor stub
	}
	
	@Resource
	private IQueryService queryService;
	
	//转发服务对象
	private ITransferService transferService = null;
	
	private ITransferService transferService_sanbao = null;//三宝平台
	
	private String typeMain = "mainLink";//主链路类型
	private String typeSub = "subLink";//从链路类型
	
	private boolean outDebug = false;//调试信息输出标记
	
	private boolean outError = false;//错误信息输出标记
	
	private int  queryTimeSpanValue = 24;//查询时间线数据的时间段，24表示当前时间到24小时之前的数据
	
	private int unCheckStatusTimeLength = 60;//状态时间间隔，超过60秒则认为间隔过长，需要设置为未监测状态
	private int unCheckStatus = 2;//未监测状态

	private String queryIdGet = "jt809Command.getLastStatusData";//查询
	
	private String queryIdAdd = "jt809Command.addOneStatusData";//插入
	
	private String queryIdUpdate = "jt809Command.updateOneStatusData";//更新
	
	private boolean checkMonthDateFlg = true;//定义校验月初时间标记为true，表示允许校验 
	
	//重写线程初始化方法
	protected String threadServiceInit() {
			String msg = "";
			try {
				//初始化输出标记
				if(value1.equals("1")){
					outDebug = true;
				}
				if(value2.equals("1")){
					outError = true;
				}
				msg += initService();
			} catch (Exception e) {
				// TODO: handle exception
			}
			
			return msg;
		}
	
		//重写线程循环执行方法
		protected void threadServiceRun() {
			try {
				
				
				
				checkBasTrans();//校验联网联控809链接状态
				
				checkSanBaoTrans();//校验三宝809链接状态
				
				checkMonthDate();//校验是否为月初时间,如果是月初时间，则切割时间线

			} catch (Exception e) {
				// TODO: handle exception
				outError("校验809链接状态错误：" + e.getMessage());
				checkError();
			}
			
		}
		
		
		
		
		//////////////////////////////////////////////////////////////////////////////////功能方法
		
		
		/////////////////////////////////////////////////////////////////////根据时间判断是否需要中断间线
		
		/**
		 * 校验是否为月初时间,改为每天校验一次
		 */
		private void checkMonthDate(){
			String msg = "";
			String msgErr = "";
			try {
				Calendar calendar = Calendar.getInstance();
				int hour = calendar.get(Calendar.HOUR_OF_DAY);
				if(hour == 0){// 小时，0时
					if(calendar.get(Calendar.MINUTE) < 10){//0点10分之前开始校验
						if(checkMonthDateFlg){//允许校验
							//开始初始化月初时间线
							outInfo("当前为月初时间，开始进行时间线初始化..........................");
							
							initBasMonthDate();//初始化联网联控时间线
							initSanbaoMonthDate();//初始化三宝月初时间线
							
							checkMonthDateFlg = false;
						}
					}
				}else if(hour > 20) {
					if(!checkMonthDateFlg){
						checkMonthDateFlg = true;
					}
				}
				
			} catch (Exception e) {
				// TODO: handle exception
				msgErr += "校验是否为月初时间失败：" + e.getMessage();
			}
			
			outMsgByFlg(msg,msgErr);
		}
		
		//初始化联网联控月初时间线
		private void initBasMonthDate(){
			String name ="base";
			Date endTime = new Date();
			initOneLinkMonthDate(name, typeMain, endTime);
			initOneLinkMonthDate(name, typeSub, endTime);
		}
		
		//初始化三宝平台月初时间线
		private void initSanbaoMonthDate(){
			String name ="sanbao";
			Date endTime = new Date();
			initOneLinkMonthDate(name, typeMain, endTime);
			initOneLinkMonthDate(name, typeSub, endTime);
		}
		
		/**
		 * 初始化单个链接的月初时间线
		 * @param name
		 * @param type
		 * @param endTime
		 */
		private void initOneLinkMonthDate(String name,String type,Date endTime){
			String msg = "";
			String msgErr = "";
			try {
				Map map = getLastStatusData(name,type);
				if(map != null){
					updateOneStatusData(map, endTime);
					int status = 0;
					if(map.containsKey("status")){
						status = Integer.valueOf(map.get("status").toString());
					}
					addOneStatusData(name, type, status, endTime,endTime);
				}
				msg += "初始化月初时间线成功,数据为：name = " + name + " , type=" + type + " ,time=" + DateUtil.datetimeToString(endTime);
				
			} catch (Exception e) {
				// TODO: handle exception
				msgErr += "初始化月初时间线失败，数据为：name = " + name + " , type=" + type + " ,time=" + DateUtil.datetimeToString(endTime) + " ， 原因：" + e.getMessage();
			}
			outMsgByFlg(msg, msgErr);
		}
		
		
		
		///////////////////////////////////////////////////////////////////////////////校验链接状态
		
		/**
		 * 校验联网联控809链接状态
		 */
		private void checkBasTrans(){
			String log = "";
			String logErr = "";
			String linkName = "base" ; //链路名称
			int mainLinked = 0;//定义主链路状态为false
			int subLinked = 0;//定义从链路状态为false
			try {
				outInfo("++++++++++++++++++++++++", outDebug);
				outInfo("开始校验联网联控809链接状态...........", outDebug);
				String msg= getTransObject();
				if(msg.equals("")){
					outInfo("联网联控转发服务对象正常获取。", outDebug);
					if(transferService != null){
						mainLinked = transferService.isMainLinked() ? 1 : 0 ;
						subLinked = transferService.isSubLinked() ? 1 : 0 ;
						log += "当前809服务，主链接状态为：" + transferService.isMainLinked() + "，从链路链接状态为：" + transferService.isSubLinked();
					}else {
						logErr += "转发服务对象为空，无法获取状态数据！";
					}
				}else {//获取转发服务对象失败，默认为链接失败，更新失败信息
					logErr += "联网联控,返回信息不为空：" + msg;
				}
			} catch (Exception e) {
				// TODO: handle exception
				logErr += "校验联网联控809链接状态失败：" + e.getMessage();
			}
			
			outMsgByFlg(log, logErr);
			
			//更新到数据库
			updateLinkedStatus(linkName,typeMain,mainLinked);
			updateLinkedStatus(linkName, typeSub, subLinked);
			
			
		}
			
		
		/**
		 * 校验三宝809链接状态
		 */
		private void checkSanBaoTrans(){
			
			String log = "";
			String logErr = "";
			String linkName = "sanbao" ; //链路名称
			int mainLinked = 0;//定义主链路状态为false
			int subLinked = 0;//定义从链路状态为false
			try {
				outInfo("+++++++++++++++", outDebug);
				outInfo("开始校验三宝809链接状态...........", outDebug);
				
				String msg= getTransObjectSanbao();
				if(msg.equals("")){
					log += "三宝转发服务对象正常获取。";
					if(transferService_sanbao != null){
						mainLinked = transferService_sanbao.isMainLinked() ? 1 : 0 ;
						subLinked = transferService_sanbao.isSubLinked() ? 1 : 0 ;
						log += "三宝809服务，主链接状态为：" + transferService_sanbao.isMainLinked() + "，从链路链接状态为：" + transferService_sanbao.isSubLinked();
					}else {
						logErr += "转发服务对象为空，无法获取状态数据！";
					}
				}else {//获取转发服务对象失败，默认为链接失败，更新失败信息
					logErr += "三宝服务,返回信息不为空：" + msg;
				}
			} catch (Exception e) {
				// TODO: handle exception
				logErr += "校验三宝809链接状态失败：" + e.getMessage();
			}
			
			//输出信息
			outMsgByFlg(log, logErr);
			
			//更新到数据库
			updateLinkedStatus(linkName,typeMain,mainLinked);
			updateLinkedStatus(linkName, typeSub, subLinked);
			
			
		}
		
		
		
		/**
		 * 更新链接状态
		 * @param name
		 * @param type
		 * @param status
		 */
		private void updateLinkedStatus(String name,String type , int status){
			String msg = "";
			String msgErr = "";
			try {
				outInfo("更新链路状态：" + name + "， 链路类型：" + type + " ， 状态：" + status, outDebug);
				Date endTime = new Date();//当前状态时间
				Map map = getLastStatusData(name, type);
				if(map != null){//获取到最后一条状态数据
					outInfo("当前链路最后一条状态数据为：" + map.toString() , outDebug);
					//判断状态间隔是否合法
					if(map.containsKey("endTime")){
						Date lastTime = DateUtil.stringToDateTime(map.get("endTime").toString());
						int length = (int) ((endTime.getTime() - lastTime.getTime()) / 1000);
						outInfo("此次状态距离最后一个状态数据的结束时间距离为：" + length + "， 秒", outDebug);
						if( length > unCheckStatusTimeLength ){
							//超过时间阀，认为有未监测状态
							outInfo("需要添加未监测状态时间线！", outDebug);
							//添加未监测状态数据
							addOneStatusData(name, type, unCheckStatus, lastTime,endTime);
							//添加新的状态数据----------------------------------------------- 添加
							addOneStatusData(name, type, status, endTime,endTime);
						}else {
							//未超过时间阀，认为状态延续
							if(map.containsKey("status")){
								//更新最后一条数据--------------------------------------------------- 更新
								updateOneStatusData(map, endTime);
								if(Integer.valueOf(map.get("status").toString()) != status){
									//状态不同，需要新增一条状态数据------------------------------- 添加
									addOneStatusData(name, type, status, endTime,endTime);
								}
							}else {
								//没有状态数据
								msgErr += "获取到的最后一条状态数据中没有状态信息：" + map.toString();
							}
						}
					}else {
						msgErr += "获取到的最后一条状态数据中没有结束时间信息：" + map.toString();
					}
					
				}else {
					//没有状态数据，需要新增----------------------------------------------- 添加
					outInfo("没有找到最后一条数据，需要新增一条数据！", outDebug);
					addOneStatusData(name, type, status, endTime,endTime);
				}
			} catch (Exception e) {
				// TODO: handle exception
				msgErr += "更新单个链接状态失败，name=" + name + " , type = " + type + " , status = " + status + " ，原因" + e.getMessage();
			}
			
			outMsgByFlg(msg, msgErr);
		}
		
		
		
		/**
		 * 	获取最后一条状态数据
		 * @param name
		 * @param type
		 * @param status
		 * @return
		 */
		private Map getLastStatusData(String name,String type){
			Map result = null;
			try {
				Map map = new HashMap ();
				map.put("name", name);
				map.put("type", type);
				Date now = new Date();
				map.put("start", new Date(now.getTime() - queryTimeSpanValue * 60 * 60 * 1000));
				List list = queryService.query(queryIdGet, map);
				if(list != null && list.size() > 0){
					result = (Map) list.get(0);
				}
				
			} catch (Exception e) {
				// TODO: handle exception
				result = null;
				outError("获取最后一条状态数据失败：name=" + name + " , type=" + type  + " ,原因：" + e.getMessage(), 
						outError);
				e.printStackTrace();
			}
			return result;
		}
		
		
		/**
		 * 新添加一条状态数据
		 * @param map
		 */
		private void addOneStatusData(String name,String type,int status,Date startTime,Date endTime){
			String msg = "";
			String msgErr = "";
			try {
				Map map = new HashMap();
				map.put("createDate", endTime);
				map.put("updateDate", endTime);
				map.put("name", name);
				map.put("type", type);
				map.put("status", status);
				map.put("startTime", startTime);	
				map.put("endTime", endTime);
				int length = 0;
				if(startTime != null && endTime != null){
					length = (int) Math.abs((endTime.getTime() - startTime.getTime())/1000);
				}
				map.put("length", length);
				if(queryService != null){
					queryService.insert(queryIdAdd,map);
					if(map.containsKey("id") && Integer.valueOf(map.get("id").toString()) > 0){
						msg += "插入新的状态数据成功，数据为：" + map.toString();
					}else {
						msgErr += "插入新的平台连接状态数据失败，数据为：" + map.toString();
					}
				}else {
					msgErr += "数据库服务对象为空，无法进行插入数据库操作";
				}
			} catch (Exception e) {
				// TODO: handle exception
				msgErr += "添加新的809状态数据失败：name=" + name + " , type=" + type + " , status=" + status + " , endTime = " + endTime.toString() + e.getMessage(); 
			}
			outInfo(msg, outDebug);
			outError(msgErr, outError);
		}
		
		
		/**
		 * 更新一个数据的状态信息
		 * @param id
		 * @param endTime
		 */
		private void updateOneStatusData(Map map,Date endTime){
			String msg = "";
			String msgErr = "";
			try {
				//获取时间
				Date start = DateUtil.stringToDateTime(map.get("startTime").toString());
				long length = (endTime.getTime() - start.getTime()) /1000;
				if(length >= 0){
					Map updateMap = new HashMap ();
					updateMap.put("id", map.get("id"));
					updateMap.put("endTime", endTime);
					updateMap.put("length", length);
					queryService.update(queryIdUpdate, updateMap);
				}else {
					msgErr += "更新链接状态数据失败：结束时间大于开始时间，不更新。当前数据：" + map.toString() + " ， 结束时间：" + DateUtil.datetimeToString(endTime);
				}
				
				//更新数据
			} catch (Exception e) {
				// TODO: handle exception
				msgErr += "更新链接状态数据失败，当前数据：" + map.toString() + "，原因：" + e.getMessage();
			}
			
			outInfo(msg, outDebug);
			outError(msgErr, outError);
		}
		
		
		/**
		 * 获取联网联控平台转发服务对象
		 * @return
		 */
 		private String getTransObject(){
			String msg = "";
			String log = "";
			try {
				if(transferService == null){
//					System.out.println("当前转发服务对象为空！");
					transferService = SpringApplicationContextHolder.getBean("transferService");
//					System.out.println("获取转发服务对象成功！");
					if(transferService != null){
						log = "转发服务对象不为空"+transferService.toString();
					}else {
						log = "转发服务对象为空！";
					}
				}else {
					log = "服务对象不为空，不用获取：" + transferService.toString();
				}
			} catch (Exception e) {
				// TODO: handle exception
				transferService = null;
				msg = "获取转发服务对象失败：" + e.getMessage();
				log = msg;
			}
			outInfo(log, outDebug);
			return msg;
		}
	
		
		/**
		 * 获取三宝平台转发服务对象
		 * @return
		 */
		private String getTransObjectSanbao(){
			String msg = "";
			String log = "";
		try {
			if(transferService_sanbao == null){
//				System.out.println("当前转发服务对象为空！");
				transferService_sanbao = SpringApplicationContextHolder.getBean("transferService_sanbao");
//				System.out.println("获取转发服务对象成功！");
				if(transferService_sanbao != null){
					log = "三宝转发服务对象不为空"+transferService_sanbao.toString();
				}else {
					log = "三宝转发服务对象为空！";
				}
			}else {
				log = "三宝服务对象不为空，不用获取：" + transferService_sanbao.toString();
			}
		} catch (Exception e) {
			// TODO: handle exception
			transferService_sanbao = null;
			msg = "获取三宝转发服务对象失败：" + e.getMessage();
			log = msg;
		}
		
		outInfo(log, outDebug);
		return msg;
		}


		
		//初始化所需服务
		private String  initService() {
			String msg = "";
			if(queryService == null) {
				queryService = SpringApplicationContextHolder.getBean("queryService");
				if(queryService == null) {
					msg += "查询服务对象创建失败！";
				}
			}
			return msg;
		}

		
		/**
		 * 根据标记，输出信息
		 * @param msg 调试信息
		 * @param msgErr 错误信息
		 */
		private void outMsgByFlg(String msg ,String msgErr){
			outInfo(msg, outDebug);
			outError(msgErr, outError);
		}
}
